package com.vca.service.service.Impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.XML;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.vca.common.constants.WxOpenAiTestConstants;
import com.vca.common.constants.WxOpenAiUrlConstants;
import com.vca.common.exception.VcaException;
import com.vca.common.request.WxOpenAiSendMsgRequest;
import com.vca.common.result.CommonResult;
import com.vca.common.utils.RedisUtil;
import com.vca.common.utils.RestTemplateUtil;
import com.vca.common.utils.VcaUtil;
import com.vca.common.utils.openai.WXBizMsgCrypt;
import com.vca.service.service.WxOpenAiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.util.Map;

@Slf4j
@Service
public class WxOpenAiServiceImpl implements WxOpenAiService  {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RestTemplateUtil restTemplateUtil;

    @Override
    public CommonResult receiveMsg(String msg) throws Exception{

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        StringReader sr = new StringReader(msg);
        InputSource is = new InputSource(sr);
        Document document = db.parse(is);

        Element root = document.getDocumentElement();
        NodeList nodelist1 = root.getElementsByTagName("Encrypt");
        NodeList nodelist2 = root.getElementsByTagName("MsgSignature");
        NodeList nodelist3 = root.getElementsByTagName("TimeStamp");
        NodeList nodelist4 = root.getElementsByTagName("Nonce");

        String encrypt = nodelist1.item(0).getTextContent();
        String msgSignature = nodelist2.item(0).getTextContent();
        String timeStamp = nodelist3.item(0).getTextContent();
        String nonce = nodelist4.item(0).getTextContent();

        String fromXML = String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT, encrypt);
        log.info("fromXML: " + fromXML);

        // 第三方收到公众号平台发送的消息
        WXBizMsgCrypt pc=new WXBizMsgCrypt(WxOpenAiTestConstants.OPEN_Ai_TOKEN,WxOpenAiTestConstants.OPEN_AI_ENCODING_AES_KEY,WxOpenAiTestConstants.OPEN_AI_APPID);
        //获得解密后的xml
        String afterDecrpt = pc.decryptMsg(msgSignature, timeStamp, nonce, fromXML);
        //将xml 转为json
        String jsonString = JSON.toJSONString(XML.toJSONObject(afterDecrpt));
        // 截取json多余字段并转为map
        Map msgMap = JSON.parseObject(jsonString.substring(7,jsonString.length()-1), Map.class);
        //获取infotype,注：微信开放平台文档中标明固定为："component_verify_ticket",但参考其他代码，还包含authorized？？？
        String infotype = ObjectUtil.isNotEmpty(msgMap.get("InfoType"))?(String) msgMap.get("InfoType"):"";
        switch (infotype) {
            case "component_verify_ticket":   //验证票据
                String ComponentVerifyTicket =(String)msgMap.get("ComponentVerifyTicket");
                //将票据值写入Redis缓存中
                redisUtil.set("ComponentVerifyTicket",ComponentVerifyTicket);
                log.info("component_verify_ticket:" + ComponentVerifyTicket);
                break;
            //用户取消授权
            case "unauthorized":
                break;
            default:
        }
        return CommonResult.success(msgMap);
    }

    @Override
    public CommonResult sendMsg(WxOpenAiSendMsgRequest sendMsg) throws Exception {
        if(ObjectUtil.isEmpty(sendMsg)){
            throw new VcaException("请勿发送空值");
        }
        if(ObjectUtil.isEmpty(sendMsg.getAppId())){
            throw new VcaException("请勿发送空值");
        }
        String appId = String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT_APPID,sendMsg.getAppId());
        if(ObjectUtil.isEmpty(sendMsg.getOpenId())){
            throw new VcaException("请勿发送空值");
        }
        String openId=String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT_OPENID,sendMsg.getOpenId());
        if(ObjectUtil.isEmpty(sendMsg.getChannel())){
            throw new VcaException("请勿发送空值");
        }
        String channel="<channel>"+sendMsg.getChannel()+"</channel>";
        if(ObjectUtil.isEmpty(sendMsg.getKefuName())){
            throw new VcaException("请勿发送空值");
        }
        String kefuname=String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT_KEFUNAME,sendMsg.getKefuName());
        if(ObjectUtil.isEmpty(sendMsg.getKefuAvatar())){
            throw new VcaException("请勿发送空值");
        }
        String kefuavatar=String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT_KEFUAVATAR,sendMsg.getKefuAvatar());
        String text=String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT_MSG,sendMsg.getMsg());

        String msg="<xml>"+appId+openId+text+channel+kefuname+kefuavatar+"</xml>";
        log.info("msg------------>{}",msg);
        long timestamp = System.currentTimeMillis();
        Integer nonce = VcaUtil.randomCount(100000, 999999);
        WXBizMsgCrypt pc=new WXBizMsgCrypt(WxOpenAiTestConstants.OPEN_Ai_TOKEN,WxOpenAiTestConstants.OPEN_AI_ENCODING_AES_KEY,WxOpenAiTestConstants.OPEN_AI_APPID);
        String encryptMsg = pc.encryptMsg(msg, String.valueOf(timestamp), String.valueOf(nonce));
        String encrypted  = "{ \"encrypt\":\"" +encryptMsg+"\"}";
//        JSONObject jsonObject = restTemplateUtil.postJsonDataAndReturnJson(WxOpenAiUrlConstants.SEND_MSG_URL,JSON.parseObject(encrypted.replaceAll("\n","")));
        return CommonResult.success(encrypted.replaceAll("\n",""));
    }

    @Override
    public CommonResult change(WxOpenAiSendMsgRequest sendMsg)throws Exception{
        if(ObjectUtil.isEmpty(sendMsg)){
            throw new VcaException("请勿发送空值");
        }
        if(ObjectUtil.isEmpty(sendMsg.getAppId())){
            throw new VcaException("请勿发送空值");
        }
        String appId = String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT_APPID,sendMsg.getAppId());
        if(ObjectUtil.isEmpty(sendMsg.getOpenId())){
            throw new VcaException("请勿发送空值");
        }
        String openId=String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT_OPENID,sendMsg.getOpenId());
        String msg="<xml>"+appId+openId+"</xml>";
        if(ObjectUtil.isNotEmpty(sendMsg.getType())){
            String type=String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT_TYPE,sendMsg.getType());
            msg="<xml>"+appId+openId+type+"</xml>";
        }
        log.info("msg------------>{}",msg);
        long timestamp = System.currentTimeMillis();
        Integer nonce = VcaUtil.randomCount(100000, 999999);
        WXBizMsgCrypt pc=new WXBizMsgCrypt(WxOpenAiTestConstants.OPEN_Ai_TOKEN,WxOpenAiTestConstants.OPEN_AI_ENCODING_AES_KEY,WxOpenAiTestConstants.OPEN_AI_APPID);
        String encryptMsg = pc.encryptMsg(msg, String.valueOf(timestamp), String.valueOf(nonce));
        String encrypted  = "{ \"encrypt\":\"" +encryptMsg+"\"}";
        JSONObject jsonObject = restTemplateUtil.postJsonDataAndReturnJson(WxOpenAiUrlConstants.KEFUSTATE_CHANG_URL,JSON.parseObject(encrypted.replaceAll("\n","")));
        return CommonResult.success(encrypted.replaceAll("\n",""));
    }

    @Override
    public CommonResult getKefustate(WxOpenAiSendMsgRequest sendMsg)throws Exception {
        if(ObjectUtil.isEmpty(sendMsg)){
            throw new VcaException("请勿发送空值");
        }
        if(ObjectUtil.isEmpty(sendMsg.getAppId())){
            throw new VcaException("请勿发送空值");
        }
        String appId = String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT_APPID,sendMsg.getAppId());
        if(ObjectUtil.isEmpty(sendMsg.getOpenId())){
            throw new VcaException("请勿发送空值");
        }

        String openId=String.format(WxOpenAiTestConstants.OPEN_AI_XML_FORMAT_OPENID,sendMsg.getOpenId());
        String msg="<xml>"+appId+openId+"</xml>";
        log.info("msg------------>{}",msg);
        long timestamp = System.currentTimeMillis();
        Integer nonce = VcaUtil.randomCount(100000, 999999);
        WXBizMsgCrypt pc=new WXBizMsgCrypt(WxOpenAiTestConstants.OPEN_Ai_TOKEN,WxOpenAiTestConstants.OPEN_AI_ENCODING_AES_KEY,WxOpenAiTestConstants.OPEN_AI_APPID);
        String encryptMsg = pc.encryptMsg(msg, String.valueOf(timestamp), String.valueOf(nonce));
        String encrypted  = "{ \"encrypt\":\"" +encryptMsg+"\"}";
        JSONObject jsonObject = restTemplateUtil.postJsonDataAndReturnJson(WxOpenAiUrlConstants.KEFUSTATE_GET_URL,JSON.parseObject(encrypted.replaceAll("\n","")));
        return CommonResult.success(encrypted.replaceAll("\n",""));
    }
}
